home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / dd / dbug.c < prev    next >
C/C++ Source or Header  |  1997-09-09  |  14KB  |  492 lines

  1. /*
  2.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  3.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  4.  *    DICE-LICENSE.TXT.
  5.  */
  6. #include    "defs.h"
  7. #include    "dbug_protos.h"
  8.  
  9.  
  10. #define EXECBASE (*(struct ExecBase **)4)
  11. //#define THISPROC    ((struct Process *)(EXECBASE->ThisTask))
  12. #define THISPROC    ((struct Process *)(SysBase->ThisTask))
  13.  
  14. // ************************************************************************
  15.  
  16. Prototype void        Newline(void);
  17. Prototype void        PrintAddress(ULONG addr);
  18. Prototype void        OffsetAddressBuf(ULONG addr, char *buf);
  19.  
  20. Prototype void        InitCommand(void);
  21. Prototype void        InitModes(void);
  22. Prototype void        RefreshCommand(int fullRefresh);
  23. Prototype void        RefreshPrompt(BOOL fullRefresh);
  24. Prototype void        RefreshWindow(int fullRefresh);
  25. Prototype void        RefreshAllWindows(int fullRefresh);
  26. Prototype void        SetDisplayMode(WORD, BOOL);
  27.  
  28. Prototype void        ReadPrefs(void);
  29. Prototype void        WritePrefs(void);
  30.  
  31. Prototype void        abort(void);
  32. Prototype BOOL        ParseArgToken(char *buf);
  33. Prototype ULONG     OnOffToggle(char *arg, ULONG val, ULONG mask);
  34. Prototype int        main(int ac, char *av[]);
  35. Prototype LONG        CalcDisplayLines(void);
  36. Prototype void        SetModeSave(WORD mode);
  37. Prototype ULONG        ValidMemCheck(ULONG address);
  38.  
  39. Prototype __stkargs void kprintf(unsigned char *arg, ...);
  40.  
  41. // ***********************************************************************
  42.  
  43. Prototype UBYTE     LineBuf[128];
  44. Prototype UBYTE     DirBuf[128];
  45. Prototype WORD        ForceFullRefresh;
  46. Prototype UBYTE     RexxReplyString[MAX_REXX_REPLY];
  47. Prototype UBYTE     DefaultPubName[128];
  48. Prototype char        lastCommand[128];
  49. Prototype int        RStepFlag;
  50. Prototype char        rexxhostname[16];
  51.  
  52. // ************************************************************************
  53.  
  54. DPREFS        dprefs = { 0,0,640,200 };
  55. ULONG        ModeTopSave[MAX_MODES];
  56. ULONG        ModeSubSave[MAX_MODES];
  57. LONG        CommonAddrTable[MAX_MODES];
  58. UBYTE        LineBuf[128];
  59. UBYTE         DefaultPubName[128];
  60. WORD        ForceFullRefresh;
  61.  
  62. char        targetName[128];
  63. __aligned char    exeCommandName[128];    // cli_CommandName of debugged program
  64. char        lastCommand[128];
  65. char        commandLine[128];
  66. UBYTE         RexxReplyString[MAX_REXX_REPLY];
  67. UBYTE         DirBuf[128];
  68. // UWORD        commandCol = 0, commandEnd = 0;
  69. UWORD commandCol = 0;
  70. UWORD commandEnd = 0;
  71.  
  72. int        RStepFlag = 0;
  73.  
  74. // ************************************************************************
  75.  
  76. void    Newline(void) {
  77.     ScrEOL(); 
  78.     ScrPlain(); 
  79.     ScrPutNewline();
  80.     ScrFlush();
  81. }
  82.  
  83. void    PrintAddress(ULONG addr) {
  84.     if (CurDisplay->ds_DisplayOffsets) {
  85.         char    *s = NearestValue(addr);
  86.  
  87.         if (s) {
  88.             ULONG    val;
  89.             LookupSymbol(s, &val);
  90.             ScrPrintf("%s + $%04X\t", s, addr - val);
  91.             return;
  92.         }
  93.     }
  94.     ScrPrintf("$%08X ", addr);
  95. }
  96.  
  97. void OffsetAddressBuf(ULONG addr, char *buf)
  98. {
  99.     char    *s = NearestValue(addr);
  100.  
  101.     if (s) {
  102.         ULONG    val;
  103.         LookupSymbol(s, &val);
  104.         sprintf(buf, "%s+%04x", s, addr - val);
  105.     } else {
  106.         sprintf(buf, "%08x", addr);
  107.     }
  108. }
  109.  
  110.  
  111. void    RefreshPrompt(BOOL fullRefresh) {
  112.     DEBUG    *debug = FindNearestDebug(CurDisplay->ds_WindowTop);
  113.     char    *s = debug ? debug->sourceName : "NO SOURCE";
  114.     int len = CurDisplay->ds_PromptStart+1;
  115.  
  116.     ScrPlain();    // put line back to normal
  117.     ScrRowCol(CurDisplay->ds_ScrRows-2, len);
  118.     CurDisplay->ds_PromptLen = ScrPrintf("(%s): ", s) + len;
  119. }
  120.  
  121.  
  122. // ************************************************************************
  123.  
  124. void    InitCommand(void) {
  125.     if(stricmp(commandLine,"again"))strcpy(lastCommand, commandLine);
  126.     strcpy(commandLine, "");
  127.     commandCol = commandEnd = 0;
  128. }
  129.  
  130. void    InitModes(void) {
  131.  
  132.     WORD    i;
  133.  
  134.     //  Initialize the topWindow save array for the various display
  135.     //  modes to -1
  136.     //
  137.     //  Initialize the CommonAddrTable[] such that the dism/source/mixed
  138.     //  modes share a common topWindow save address and the hex display
  139.     //  modes share a common topWinodw save address
  140.  
  141.     for (i = 0; i < MAX_MODES; ++i) {
  142.         ModeTopSave[i] = -1;
  143.         ModeSubSave[i] = 0;
  144.         CommonAddrTable[i] = i;
  145.     }
  146.  
  147.     CommonAddrTable[DISPLAY_SOURCE] = DISPLAY_DISM;
  148.     CommonAddrTable[DISPLAY_MIXED] = DISPLAY_DISM;
  149.     CommonAddrTable[DISPLAY_WORDS] = DISPLAY_BYTES;
  150.     CommonAddrTable[DISPLAY_LONGS] = DISPLAY_BYTES;
  151.  
  152.     ModeTopSave[DISPLAY_HUNKS] = 0;
  153.     ModeTopSave[DISPLAY_BREAK] = 0;
  154.     ModeTopSave[DISPLAY_SYMBOL] = 0;
  155.     ModeTopSave[DISPLAY_HELP] = 0;
  156. }
  157.  
  158. void    RefreshCommand(int fullRefresh) {
  159.     DBugDisp *disp = CurDisplay;
  160.  
  161.     ScrRowCol(CurDisplay->ds_ScrRows-2, disp->ds_PromptLen);
  162.     commandLine[commandEnd] = '\0';
  163.     ScrPlain();
  164.     ScrPuts(commandLine);
  165.     ScrEOL();
  166.     ScrRowCol(CurDisplay->ds_ScrRows-2, commandCol+disp->ds_PromptLen);
  167.     if(fullRefresh)ScrFlush();
  168.     if(fullRefresh == -1)drawdoublebox(); // redraw box if screen was cleared
  169.  
  170. }
  171.  
  172. // ************************************************************************
  173.  
  174. void    SetDisplayMode(WORD mode, BOOL setPrefered) {
  175.     ULONG addr;
  176.     SHORT    displayMode = CurDisplay->ds_DisplayMode;
  177.  
  178.  
  179.     if (setPrefered) {
  180.         CurDisplay->ds_PreferedMode = mode;
  181.     }
  182.  
  183.     if (displayMode != mode) {
  184.         ModeTopSave[CommonAddrTable[displayMode]] = CurDisplay->ds_WindowTop;
  185.         ModeSubSave[CommonAddrTable[displayMode]] = CurDisplay->ds_WindowTopLine;
  186.         CurDisplay->ds_DisplayMode = displayMode = mode;
  187.         if ((addr = ModeTopSave[CommonAddrTable[mode]]) != (ULONG)-1)
  188.             CurDisplay->ds_WindowTop = addr;
  189.         CurDisplay->ds_WindowTopLine = ModeSubSave[CommonAddrTable[mode]];
  190.     }
  191.         // if the register command hasn't been used, stay in auto mode
  192.     if(!CurDisplay->ds_RegTouched) {
  193.         if((mode == DISPLAY_MIXED) || (mode == DISPLAY_DISM))
  194.          CurDisplay->ds_RegFlag = 1;
  195.         else CurDisplay->ds_RegFlag = 0;
  196.     }
  197. }
  198.  
  199. void    SetModeSave(WORD mode) {
  200.     ModeTopSave[CommonAddrTable[mode]] = CurDisplay->ds_WindowTop;
  201.     ModeSubSave[CommonAddrTable[mode]] = CurDisplay->ds_WindowTopLine;
  202. }
  203.  
  204. // ************************************************************************
  205.  
  206. void    RefreshAllWindows(int fullRefresh)
  207. {
  208.     DBugDisp *disp, *odisp = CurDisplay;
  209.  
  210.     RefreshWindow(fullRefresh);    // do current display first
  211.                 // (its the focus of attention)
  212.     for (disp = (DBugDisp *)DisplayList.lh_Head; disp->ds_Node.ln_Succ; disp = (DBugDisp *)disp->ds_Node.ln_Succ) {
  213.     if(disp != odisp) {    // do not do original window again
  214.         CurDisplay = disp;
  215.         RefreshWindow(fullRefresh);
  216.     }
  217.     }
  218.     CurDisplay = odisp;
  219. }
  220.  
  221. // ************************************************************************
  222.  
  223. void    RefreshWindow(int fullRefresh) {
  224.     WORD        lines, count;
  225.     DBugDisp    *disp = CurDisplay;
  226.     int         clearStatus = fullRefresh;
  227.  
  228.     fullRefresh = (fullRefresh) ? 1 : 0;
  229.     // check for force or mode change
  230.     if ((disp->ds_LastRefreshMode != disp->ds_DisplayMode) || (disp->ds_LastRefreshTop != disp->ds_WindowTop) || ForceFullRefresh ) {
  231.         fullRefresh = 1;
  232.         ForceFullRefresh = 0;
  233.     }
  234.  
  235.     disp->ds_LastRefreshMode = disp->ds_DisplayMode;
  236.     disp->ds_LastRefreshTop = disp->ds_WindowTop;
  237.     GetWindowSize();
  238.     lines = disp->ds_ScrRows - 1;
  239.  
  240.     ScrCursoff();
  241.     disp->ds_ScrTop = disp->ds_RegFlag;  // 0 for no registers, 1 otherwise
  242.  
  243.     if (clearStatus == -1)ScrClr();
  244.     else if (fullRefresh)ScrScrollClr();
  245.  
  246.     ScrHome();
  247.     count = RefreshRegisters(lines, (BOOL)fullRefresh);
  248.     lines -= count;
  249.     disp->ds_ScrTop += count;
  250.     lines -= 3;    /* command line and two control lines    */
  251.  
  252.     if (lines > 0 && programState != STATE_EXITED) {
  253.         count = RefreshWatchpoints(lines, (BOOL)fullRefresh);
  254.         lines -= count;
  255.         disp->ds_ScrTop += count;
  256.     }
  257.     if (lines > 0) {
  258.         if (programState == STATE_EXITED && disp->ds_DisplayMode <= DISPLAY_MIXED) {
  259.             ScrPrintf("*** Program exited code %d", programD0);
  260.         }
  261.         else {
  262.             switch (disp->ds_DisplayMode) {
  263.                 case DISPLAY_DISM:    lines -= RefreshDism(lines, (BOOL)fullRefresh); break;
  264.                 case DISPLAY_SOURCE:    lines -= RefreshMixed(lines, (BOOL)fullRefresh, disp->ds_WindowTop, disp->ds_WindowTopLine, 0); break;
  265.                 case DISPLAY_MIXED:    lines -= RefreshMixed(lines, (BOOL)fullRefresh, disp->ds_WindowTop, disp->ds_WindowTopLine, 1); break;
  266.                 case DISPLAY_BYTES:    lines -= RefreshBytes(lines, (BOOL)fullRefresh, disp->ds_WindowTop); break;
  267.                 case DISPLAY_WORDS:    lines -= RefreshWords(lines, (BOOL)fullRefresh, disp->ds_WindowTop); break;
  268.                 case DISPLAY_LONGS:    lines -= RefreshLongs(lines, (BOOL)fullRefresh, disp->ds_WindowTop); break;
  269.                 case DISPLAY_HUNKS:    lines -= RefreshHunks(lines, (BOOL)fullRefresh, disp->ds_WindowTop); break;
  270.                 case DISPLAY_BREAK:    lines -= RefreshBreakpoints(lines, (BOOL)fullRefresh); break;
  271.                 case DISPLAY_HELP:    lines -= RefreshHelp(lines, (BOOL)fullRefresh, disp->ds_WindowTop); break;
  272.                 case DISPLAY_SYMBOL:    lines -= RefreshSymbols(lines, (BOOL)fullRefresh, disp->ds_WindowTop); break;
  273.                 case DISPLAY_DOSBASE:
  274.                 case DISPLAY_PROCESS:
  275.                 case DISPLAY_INFO:
  276.                 case DISPLAY_EXECBASE:
  277.                 case DISPLAY_RESOURCES:
  278.                 case DISPLAY_INTRS:
  279.                 case DISPLAY_PORTS:
  280.                 case DISPLAY_TASKS:
  281.                 case DISPLAY_LIBS:
  282.                 case DISPLAY_DEVICES:
  283.                 case DISPLAY_MEMLIST:
  284.                 case DISPLAY_REXXLIST:
  285.                 case DISPLAY_SYMLIST:
  286.                             lines -= RefreshList(lines, (BOOL)fullRefresh, disp->ds_WindowTop); break;
  287.                 default:        break;
  288.             }
  289.         }
  290.     }
  291.     while (lines > 0) {
  292.         Newline();
  293.         lines--;
  294.     }
  295.  
  296.     RefreshFKeys(clearStatus);
  297.         RefreshPrompt(clearStatus);
  298.     RefreshCommand(clearStatus);
  299.  
  300.     ScrCurson();
  301.     disp->ds_LastRefreshMode = disp->ds_DisplayMode;
  302.     
  303. }
  304.  
  305. /* utility routine to calculate the number of available lines in the display */
  306. LONG    CalcDisplayLines(void)
  307. {
  308.     LONG lines = CurDisplay->ds_ScrRows - 1;
  309.     WORD regcount = 0;
  310.     GetWindowSize();
  311.     ScrHome();
  312.     // subtract register display, command line, and two control lines
  313.     // to find how many lines we should look back
  314.     // note:  no register display normally in source mode
  315.     if(CurDisplay->ds_RegFlag)regcount = (lines > 5) ? 5 : lines;
  316.     lines = CurDisplay->ds_ScrRows - 6 - regcount;
  317.     return(lines);
  318. }
  319.  
  320. // ************************************************************************
  321.  
  322. void    ReadPrefs(void) {
  323.     int    fd, i;
  324.     APTR wp = THISPROC->pr_WindowPtr;
  325.  
  326.     // turn off requesters
  327.     THISPROC->pr_WindowPtr = (APTR)-1;
  328.     if((fd = open("dcc_config:dd.config", O_READ)) <= 0) {
  329.         fd = open("dcc:config/dd.config", O_READ);
  330.     }
  331.     for(i=0; i<MAXCOMMAND; i++)dprefs.alias[i]=0;    // clear entire alias table
  332.  
  333.     if (fd == -1) {
  334.         dprefs.top = dprefs.left = 0;
  335.         dprefs.width = 640; dprefs.height = 200;
  336.         dprefs.DefaultOffset = 0;
  337.         dprefs.DefaultMode = DISPLAY_SOURCE;
  338.     }
  339.     else {
  340.         read(fd, &dprefs, sizeof(DPREFS));
  341.         close(fd);
  342.     }
  343.     THISPROC->pr_WindowPtr = wp;
  344. }
  345.  
  346. void    WritePrefs(void) {
  347.     int    fd;
  348.     APTR wp = THISPROC->pr_WindowPtr;
  349.  
  350.     // turn off requesters
  351.     THISPROC->pr_WindowPtr = (APTR)-1;
  352.     if((fd = open("dcc_config:dd.config", O_WRITE)) <= 0) {
  353.         fd = open("dcc:config/dd.config", O_WRITE);
  354.     }
  355.     if (fd != -1) {
  356.         dprefs.DefaultOffset = CurDisplay->ds_DisplayOffsets;
  357.         dprefs.DefaultMode = CurDisplay->ds_DisplayMode;
  358.  
  359.         write(fd, &dprefs, sizeof(DPREFS));
  360.         close(fd);
  361.     }
  362.     THISPROC->pr_WindowPtr = wp;
  363. }
  364.  
  365.  
  366. // ************************************************************************
  367.  
  368. void    abort(void) {
  369.     CleanMem();
  370. }
  371.  
  372. BOOL    ParseArgToken(char *buf) {
  373.     char    *b = buf;
  374.  
  375.     while (argSize > 0 && *args == ' ') { 
  376.         args++; 
  377.         argSize--;
  378.     }
  379.     if (*args == '"') {
  380.         args++;
  381.         argSize--;
  382.         while (argSize > 0 && *args != '"' && *args != '\n') {
  383.         *buf++ = *args++;
  384.         argSize--;
  385.         }
  386.         if (argSize > 0 && *args == '"') {
  387.         args++;
  388.         argSize--;
  389.         }
  390.     }
  391.     else {
  392.         while (argSize > 0 && *args != ' ' && *args != '\n') { 
  393.         *buf++ = *args++;
  394.         argSize--;
  395.         }
  396.     }
  397.     *buf = '\0';
  398.     return (b != buf);
  399. }
  400.  
  401. char    *RexxHostName = NULL; //REXXPORTNAME;
  402. char    rexxhostname[16];
  403.  
  404. int    main(int ac, char *av[]) {
  405.     int i=1;
  406.     atexit(abort);
  407.     InitConsole();
  408.     if (RexxSysBase == NULL) {
  409.         puts("Unable to open rexxsyslib.library.");
  410.         exit(20);
  411.     }
  412.  
  413.     // port name kludge
  414.     {
  415.         int num = CreateDiceRexxPort(NULL,REXXPORTNAME);
  416.         sprintf(rexxhostname,"%s.%02d",REXXPORTNAME,num);
  417.     }
  418.  
  419.     if (!ParseArgToken(targetName)) {
  420.         printf("Usage: DBug <options> program [program_args...]\n");
  421.         printf("; Before using DBug, compile program with -d1 to add symbols\n");
  422.         exit(20);
  423.     }
  424.     {
  425.         WORD    i;
  426.         char    *ps = &targetName[0], *pd = (char *)&exeCommandName[1];
  427.  
  428.         for (i=0; i<128; i++) exeCommandName[i] = 0;
  429.         while(*pd++ = *ps++)exeCommandName[0]++;
  430.  
  431.     }
  432.     InitModes();
  433.     InitCommand();
  434.     InitBreakpoints();
  435.     memset(DirBuf,0,128);
  436.     init_function_keys();
  437.     if(((struct Library *)SysBase)->lib_Version >= 36) {
  438.         GetCurrentDirName(DirBuf,128);
  439.     }
  440.     ReadPrefs();
  441.     if (!DBugLoadSeg(targetName)) {
  442.         printf("Can't loadseg %s\n", targetName);
  443.         exit(20);
  444.     }
  445.     ScrOpen(TRUE, FALSE, NULL);
  446.     SymbolCount = CountSymbols();
  447.     ResetTarget();
  448.     CmdRexx("ddinit.dd");    // check for init file
  449.     EnterDebugger();
  450.     CmdQuit("");
  451.     return 0;
  452. }
  453.  
  454. ULONG    OnOffToggle(char *arg, ULONG val, ULONG mask) {
  455.  
  456.     if (strnicmp(arg, "on", 2) == 0) {
  457.         return(val | mask);
  458.     } else if (strnicmp(arg, "off", 3) == 0) {
  459.         return(val & ~mask);
  460.     } else {
  461.         return(val ^ mask);
  462.     }
  463. }
  464.  
  465.  
  466. // This routine checks if it is being fed a legal address for debugger
  467. // access to avoid annoying enforcer.
  468. // All display refresh routines should use it, as well as special
  469. // commands like SET
  470. //
  471. ULONG    ValidMemCheck(ULONG address) {
  472.  
  473.     // low memory check (enforcer) first
  474.     // might need an 040 specific test if 040 enforcer protects more
  475.  
  476.     if(address < 0x1000)return 0;
  477.  
  478.     // this and should only be done on the 68000
  479.     if(address & 1)address &= 0xFFFFFFFE;
  480.  
  481.     // add credit card && CDTV card && ZKick
  482.         // if (OpenResource("card.resource")) 00600000 +00550002
  483.         // if (FindResident("cdstrap")) 0x00E00000 + 00080000
  484.         // if ((((ULONG)(SysBase->LibNode.lib_Node.ln_Name)) >> 16) == 0x20) 0x00200000,0x00080000
  485.  
  486.     if( TypeOfMem((UBYTE *)address) || 
  487.     (address >= 0x00F00000 && address <= 0x00FFFFFF) ||
  488.     (address >= 0x00BC0000 && address <= 0x00BEFFFF) ||
  489.     (address >= 0x00D80000 && address <= 0x00DFFFFF))return address;
  490.     return 0;
  491. }
  492.